package hydrap2p.library;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;


public abstract class SqlList<E> implements List<E> {

	protected final ResultSet results;
	protected final int count;
	protected int pos;
	
	public class SqlListIterator implements ListIterator<E>
	{
		private int current;
		
		public SqlListIterator(){
			current=-1;
		}
		public SqlListIterator(int i)
		{
			if (i<0)
				throw new NoSuchElementException();
			if (i>=count)
				throw new NoSuchElementException();
			current=i;
		}

		@Override
		public boolean hasNext() {
			return current<count-1;
		}

		@Override
		public boolean hasPrevious() {
			return current>0;
		}

		@Override
		public E next() {
			if (hasNext())
			{
				current++;
				return get(current);
			}
			throw new NoSuchElementException();
		}

		@Override
		public int nextIndex() {
			return current+1;
		}

		@Override
		public E previous() {
			if (hasPrevious())
			{
				current--;
				return get(current);
			}
			throw new NoSuchElementException();
		}

		@Override
		public int previousIndex() {
			return current-1;
		}
		
		@Override
		public void add(E arg0) {
			throw new UnsupportedOperationException();
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}

		@Override
		public void set(E arg0) {
			throw new UnsupportedOperationException();
		}
		
	}
	
	public SqlList(ResultSet results) throws SQLException
	{
		this.results=results;
		//results.last();
		//count=results.getRow();
		count=0;
		//results.first();
		results.next();
		pos=results.getRow()-1;
	}

	@Override
	public abstract E get(int arg0);

	@Override
	public boolean contains(Object arg0) {
		for (Object i:this)
			if (i.equals(arg0))
				return true;
		return false;
	}

	@Override
	public boolean containsAll(Collection<?> arg0) {
		for (Object i:arg0)
			if (!this.contains(i))
				return false;
		return true;
	}
	
	@Override
	public int indexOf(Object arg0) {
		for (int i=0; i<count; i++)
			if (get(i).equals(arg0))
				return i;
		return -1;
	}

	@Override
	public int lastIndexOf(Object arg0) {
		for (int i=count-1; i>=0; i--)
			if (get(i).equals(arg0))
				return i;
		return -1;
	}

	@Override
	public Iterator<E> iterator() {
		return new SqlListIterator();
	}

	@Override
	public ListIterator<E> listIterator() {
		return new SqlListIterator();
	}

	@Override
	public ListIterator<E> listIterator(int arg0) {
		return new SqlListIterator(arg0);
	}

	@Override
	public int size() {
		return count;
	}

	@Override
	public boolean isEmpty() {
		return count==0;
	}

	@Override
	public List<E> subList(int arg0, int arg1) {
		List<E> sublist=new LinkedList<E>();
		for (int i=arg0; i<arg1; i++)
			sublist.add(get(i));
		return sublist;
	}
	
	protected void seek(int i) throws SQLException
	{
		try{
			while (pos<i && results.next())
			{
				pos++;
			}
			while (pos>i && results.previous())
			{
				pos--;
			}
		}
		catch (SQLException e)
		{
			e.printStackTrace();
		}
	}

	@Override
	public Object[] toArray() {
		int i=0;
		Object[] output=new Object[this.size()];
		for (E temp:this)
			output[i++]=temp;
		return output;
	}

	@Override
	public Object[] toArray(Object[] arg0) {
		return toArray();
	}
	
	/// Invalid operations on this readonly list
	
	@Override
	public boolean add(E arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void add(int arg0, E arg1) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean addAll(Collection<? extends E> arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean addAll(int arg0, Collection<? extends E> arg1) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void clear() {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean remove(Object arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public E remove(int arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean removeAll(Collection<?> arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean retainAll(Collection<?> arg0) {
		throw new UnsupportedOperationException();
	}

	@Override
	public E set(int arg0, E arg1) {
		throw new UnsupportedOperationException();
	}

}
